﻿using Abp.Application.Services.Dto;
using Abp.Domain.Repositories;
using Abp.EntityFrameworkCore.Repositories;
using Abp.Extensions;
using Abp.Linq.Extensions;
using Abp.Threading;
using Abp.UI;
using ARchGL.Platform.Authorization.Users;
using ARchGL.Platform.Electrocar.Application.Dto;
using ARchGL.Platform.Electrocar.Core;
using ARchGL.Platform.Utils;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ARchGL.Platform.Electrocar.Application
{
    /// <summary>
    /// 车身 实现
    /// </summary>
    public class CarBodysAppService : BaseService
    {
        private readonly IRepository<CarBodys, Guid> carBodysRepository;

        private readonly UserManager userManager;

        public CarBodysAppService(
            IRepository<CarBodys, Guid> _carBodysRepository,
            UserManager _userManager)
        {
            carBodysRepository = _carBodysRepository;
            userManager = _userManager;
        }

        /// <summary>
        /// 创建车身属性
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<Guid> Create(CarBodysDto input)
        {
            var entity = ObjectMapper.Map<CarBodys>(input);
            entity.CreatorUserName = userManager.UserName;
            await carBodysRepository.InsertAsync(entity);
            return entity.Id;
        }

        /// <summary>
        /// 删除车身属性
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        [HttpPost]
        public async Task Remove(EntityDto<Guid> input)
        {
            var entity = await carBodysRepository.GetAsync(input.Id);
            if (entity == null) throw new UserFriendlyException("属性不存在，请重新输入");

            var count = carBodysRepository.GetAll().Count(x => x.ParentId == entity.Id);
            if (count > 0) throw new UserFriendlyException($"该属性下有{count}条信息，不能删除");

            await carBodysRepository.DeleteAsync(entity);
        }

        /// <summary>
        /// 编辑车身属性
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task Modify(CarBodysDto input)
        {
            var entity = await carBodysRepository.GetAsync(input.Id);
            if (entity == null) throw new UserFriendlyException("属性不存在，请重新输入");
            entity.Name = input.Name;
            entity.Type = input.Type;
            entity.Value = input.Value;

            var sadf = entity.Type == 1
                ? Newtonsoft.Json.JsonConvert.DeserializeObject<ValueStruct>(input.Value)
                : Newtonsoft.Json.JsonConvert.DeserializeObject<ValueAndFileStruct>(input.Value);

            await carBodysRepository.UpdateAsync(entity);
        }

        /// <summary>
        /// 编辑车身属性排序位置
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task ModifySort(SortInput input)
        {
            var entity = await carBodysRepository.GetAsync(input.Id);
            if (entity == null) throw new UserFriendlyException("属性不存在，请重新输入");
            var sql = $"UPDATE {GetTableName<CarBodys>()} SET Sort = @Sort WHERE Id = @Id";
            var dbContext = carBodysRepository.GetDbContext().Database;

            var currentList = carBodysRepository.GetAll().Where(x => x.ProjectId == entity.ProjectId && x.ParentId == entity.ParentId).ToList();

            var type = input.Sort > entity.Sort ? +1 : -1;//获取升降标识
            int periods = type > 0 ? entity.Sort : input.Sort;//起数
            var end = type > 0 ? input.Sort : entity.Sort;//止数

            if (currentList.Any())//更新同级目录下排序位置
            {
                var sortList = currentList.Where(x => x.Sort >= periods && x.Sort <= end).OrderBy(x => x.Sort);
                foreach (var item in sortList)
                {
                    item.Sort = type > 0 ? --item.Sort : ++item.Sort;
                    if (item.Sort > currentList.Count) item.Sort = currentList.Count;//上边界
                    if (item.Sort <= 0) item.Sort = 1;//下边界
                    dbContext.ExecuteSqlCommand(sql, item.Sort, item.Id);
                }
            }
            dbContext.ExecuteSqlCommand(sql, input.Sort, entity.Id);
        }

        /// <summary>
        /// 获取车身属性-集合
        /// </summary>
        /// <param name="input">CarModelId</param>
        /// <returns></returns>
        public async Task<List<CarBodysDto>> QueryListById(EntityDto<Guid> input)
        {
            var query = carBodysRepository.GetAll()
                .WhereIf(input.Id != Guid.Empty, x => x.ProjectId == input.Id);

            var result = query.OrderBy(x => x.Sort).ToList();
            return ObjectMapper.Map<List<CarBodysDto>>(result);
        }

        /// <summary>
        /// 获取车身属性-分页数据集合
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        private async Task<PagedResultDto<ProjectsDto>> QueryListPagedList(ModelDirectorysInput input)
        {
            try
            {
                var query = carBodysRepository.GetAll()
                        .WhereIf(!input.Keywords.IsNullOrWhiteSpace(), x => x.Name.Contains(input.Keywords))
                        .WhereIf(input.ParentIdList.Any(), x => input.ParentIdList.Contains(x.ParentId));

                var result = await query.OrderBy(x => x.Sort).PageByAsync(input);
                return new PagedResultDto<ProjectsDto>(query.Count(),
                    ObjectMapper.Map<List<ProjectsDto>>(result.ToList()));
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }
}
